package br.com.loja.view.swing.model;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.Transient;
import javax.swing.table.AbstractTableModel;
import br.com.loja.util.reflection.JBean;

/**
 * @brief Classe EntityDefaultTableModel
 * @author David Luiz
 * @date 26/11/2014
 */
public class EntityDefaultTableModel<T> extends AbstractTableModel {

    private List<T> entities = new ArrayList<>();
    private List<String> columns = new ArrayList<>();
    private final Class<T> clazz;

    public EntityDefaultTableModel(Class<T> clazz) {
        this.clazz = clazz;
        this.columns = setColumns();

    }

    @Override
    public String getColumnName(int column) {

        String[] c = columns.get(column).split(":");
        return c[1];

    }

    @Override
    public int getRowCount() {
        return entities.size();
    }

    @Override
    public int getColumnCount() {
        return columns.size();
    }

    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
        T entity = entities.get(rowIndex);

        Object value;

        String[] c = columns.get(columnIndex).split(":");
        String attribute = c[0];

        JBean bean = new JBean(entity, attribute);

        value = bean.getValue();

        if (value == null) {
            return "";
        }

        if (value instanceof String) {
            return value;
        }

        if (value instanceof Boolean) {
            return (Boolean) value ? "Sim" : "Não";
        }

        return value.toString();

    }

    /**
     * @return the entities
     */
    public List<T> getEntities() {
        return entities;
    }

    /**
     * @param entities the entities to set
     */
    public void setEntities(List<T> entities) {
        this.entities = entities;
    }

    private List<String> setColumns() {

        Class<?> currentClass = clazz;

        while (currentClass.getSuperclass() != null) {

            Field[] fields = currentClass.getDeclaredFields();

            for (Field field : fields) {

                boolean p = Modifier.isStatic(field.getModifiers());
                boolean q = Modifier.isTransient(field.getModifiers());
                boolean s = field.getAnnotation(IgnoreTableModel.class) != null;

                if (p || q || s) {
                    continue;
                }

                ColumnTableModel columnTableModel = field.getAnnotation(ColumnTableModel.class);

                if (columnTableModel != null) {
                    columns.add(field.getName() + ":" + columnTableModel.label());
                } else {
                    columns.add(field.getName() + ":" + String.valueOf(field.getName().charAt(0)).toUpperCase() + field.getName().substring(1));
                }

            }

            currentClass = currentClass.getSuperclass();
        }

        return columns;
    }

}
